package com.yuncheng.spcyApi.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.PriorityBlockingQueue;

/**
 * Timer定时任务
 */
public class MyTimer {

    private static final Logger log = LoggerFactory.getLogger(MyTimer.class);

    // 锁对象
    Object locker = new Object();

    // 创建优先级阻塞队列,计时器的核心数据结构
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();

    public void schedule(Runnable runnable,long delay) {
        // 创建任务
        MyTask myTask = new MyTask(runnable,delay);
        // 将任务放进计时器
        queue.put(myTask);
        synchronized (locker) {
            // 叫醒线程
            locker.notify();
        }
    }

    public MyTimer() {
        // 内置线程重复执行计时器中的任务
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    synchronized (locker) {
                        // 取出计时器中最优先执行的任务
                        MyTask myTask = queue.take();
                        // 判断是否到达执行时间
                        if (System.currentTimeMillis() >= myTask.time) {
                            // 到达执行
                            myTask.runnable.run();
                        } else {
                            // 时间还没到
                            // 把刚才取出的任务, 重新塞回队列中.
                            // 未到达再放回计时器
                            queue.put(myTask);
                            // 让线程等待相应时间
                            locker.wait(myTask.time - System.currentTimeMillis());
                        }
                    }
                } catch (InterruptedException e) {
                    log.error("MyTimer定时任务出错->[InterruptedException]->{}", e.getMessage());
                }
            }
        });
        thread.start();
    }
}
